﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
#if !NET35
using System.Threading.Tasks;
using LCL.Network.IMessage;
using LCL.LogNet;
#endif
namespace LCL.Network.Enthernet
{
    /// <summary>
    /// 异步访问数据的客户端类，用于向服务器请求一些确定的数据信息
    /// </summary>
    public class NetSimplifyClient : NetworkDoubleBase<HslMessage, RegularByteTransform>
    {
        #region Constructor
        /// <summary>
        /// 实例化一个客户端的对象，用于和服务器通信
        /// </summary>
        /// <param name="ipAddress">服务器的ip地址</param>
        /// <param name="port">服务器的端口号</param>
        public NetSimplifyClient( string ipAddress, int port )
        {
            IpAddress = ipAddress;
            Port = port;
        }
        /// <summary>
        /// 实例化一个客户端对象，需要手动指定Ip地址和端口
        /// </summary>
        public NetSimplifyClient()
        {
            LogNet = new LogNetSingle(Utils.GetMapPath("Logs") + @"\NetSimplifyClient.txt");
        }
        #endregion
        /// <summary>
        /// 客户端向服务器进行请求，请求字符串数据，忽略了自定义消息反馈
        /// </summary>
        /// <param name="customer">用户的指令头</param>
        /// <param name="send">发送数据</param>
        /// <returns>带返回消息的结果对象</returns>
        public Result<string> ReadFromServer(NetHandle customer,string send = null)
        {
            var read = ReadFromServerBase( HslProtocol.CommandBytes( customer, Token, send ) );
            if (!read.Success) return Result.CreateFailedResult<string>( read );
            return Result.CreateSuccessResult( Encoding.Unicode.GetString( read.Data ) );
        }
        /// <summary>
        /// 客户端向服务器进行请求，请求字节数据
        /// </summary>
        /// <param name="customer">用户的指令头</param>
        /// <param name="send">发送的字节内容</param>
        /// <returns>带返回消息的结果对象</returns>
        public Result<byte[]> ReadFromServer(NetHandle customer,byte[] send)
        {
            return ReadFromServerBase( HslProtocol.CommandBytes( customer, Token, send ));
        }
        /// <summary>
        /// 客户端向服务器进行请求，请求字符串数据，并返回状态信息
        /// </summary>
        /// <param name="customer">用户的指令头</param>
        /// <param name="send">发送数据</param>
        /// <returns>带返回消息的结果对象</returns>
        public Result<NetHandle, string> ReadCustomerFromServer( NetHandle customer, string send = null )
        {
            var read = ReadCustomerFromServerBase( HslProtocol.CommandBytes( customer, Token, send ) );
            if (!read.Success) return Result.CreateFailedResult<NetHandle, string>( read );
            return Result.CreateSuccessResult( read.Data1, Encoding.Unicode.GetString( read.Data2 ) );
        }
        /// <summary>
        /// 客户端向服务器进行请求，请求字符串数据，并返回状态信息
        /// </summary>
        /// <param name="customer">用户的指令头</param>
        /// <param name="send">发送数据</param>
        /// <returns>带返回消息的结果对象</returns>
        public Result<NetHandle, byte[]> ReadCustomerFromServer( NetHandle customer, byte[] send )
        {
            return ReadCustomerFromServerBase( HslProtocol.CommandBytes( customer, Token, send ) );
        }
        /// <summary>
        /// 需要发送的底层数据
        /// </summary>
        /// <param name="send">需要发送的底层数据</param>
        /// <returns>带返回消息的结果对象</returns>
        private Result<byte[]> ReadFromServerBase( byte[] send )
        {
            var read = ReadCustomerFromServerBase( send );
            if (!read.Success) return Result.CreateFailedResult<byte[]>( read );
            return Result.CreateSuccessResult( read.Data2 );
        }
        /// <summary>
        /// 需要发送的底层数据
        /// </summary>
        /// <param name="send">需要发送的底层数据</param>
        /// <returns>带返回消息的结果对象</returns>
        private Result<NetHandle, byte[]> ReadCustomerFromServerBase( byte[] send )
        {
            // 核心数据交互
            var read = ReadFromCoreServer( send );
            if (!read.Success) return Result.CreateFailedResult<NetHandle, byte[]>( read );
            // 提炼数据信息
            byte[] headBytes = new byte[HslProtocol.HeadByteLength];
            byte[] contentBytes = new byte[read.Data.Length - HslProtocol.HeadByteLength];
            Array.Copy( read.Data, 0, headBytes, 0, HslProtocol.HeadByteLength );
            if (contentBytes.Length > 0) Array.Copy( read.Data, HslProtocol.HeadByteLength, contentBytes, 0, read.Data.Length - HslProtocol.HeadByteLength );
            int customer = BitConverter.ToInt32( headBytes, 4 );
            contentBytes = HslProtocol.CommandAnalysis( headBytes, contentBytes );
            return Result.CreateSuccessResult( (NetHandle)customer, contentBytes );
        }
#if !NET35
        /// <summary>
        /// 客户端向服务器进行异步请求，请求字符串数据
        /// </summary>
        /// <param name="customer">用户的指令头</param>
        /// <param name="send">发送数据</param>
        public Task<Result<string>> ReadFromServerAsync( NetHandle customer, string send = null )
        {
            return Task.Factory.StartNew(() => ReadFromServer(customer, send));
        }
        /// <summary>
        /// 客户端向服务器进行异步请求，请求字节数据
        /// </summary>
        /// <param name="customer">用户的指令头</param>
        /// <param name="send">发送的字节内容</param>
        /// <returns>带返回消息的结果对象</returns>
        public Task<Result<byte[]>> ReadFromServerAsync( NetHandle customer, byte[] send )
        {
            return Task.Factory.StartNew(() => ReadFromServer(customer, send));
        }
#endif
        #region Object Override
        /// <summary>
        /// 获取本对象的字符串表示形式
        /// </summary>
        /// <returns>字符串信息</returns>
        public override string ToString()
        {
            return "NetSimplifyClient[" + IpAddress + ":" + Port + "]";
        }
        #endregion
    }
}
